package cloud.seri.gateway.security.oauth2

import cloud.seri.gateway.config.oauth2.OAuth2Properties
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.springframework.mock.web.MockHttpServletRequest
import org.springframework.test.util.ReflectionTestUtils

/**
 * Tests helper functions around OAuth2 Cookies.
 *
 * @see OAuth2CookieHelper
 */
class OAuth2CookieHelperTest {

    private lateinit var oAuth2Properties: OAuth2Properties
    private lateinit var cookieHelper: OAuth2CookieHelper

    @Before
    @Throws(NoSuchMethodException::class)
    fun setUp() {
        oAuth2Properties = OAuth2Properties()
        cookieHelper = OAuth2CookieHelper(oAuth2Properties)
    }

    @Test
    fun testLocalhostDomain() {
        val request = MockHttpServletRequest()
        request.serverName = "localhost"
        val name = ReflectionTestUtils.invokeMethod<String>(cookieHelper, GET_COOKIE_DOMAIN_METHOD, request)
        Assert.assertNull(name)
    }

    @Test
    fun testComDomain() {
        val request = MockHttpServletRequest()
        request.serverName = "test.com"
        val name = ReflectionTestUtils.invokeMethod<String>(cookieHelper, GET_COOKIE_DOMAIN_METHOD, request)
        Assert.assertNull(name)        //already top-level domain
    }

    @Test
    fun testWwwDomainCom() {
        val request = MockHttpServletRequest()
        request.serverName = "www.test.com"
        val name = ReflectionTestUtils.invokeMethod<String>(cookieHelper, GET_COOKIE_DOMAIN_METHOD, request)
        Assert.assertNull(name)
    }

    @Test
    fun testComSubDomain() {
        val request = MockHttpServletRequest()
        request.serverName = "abc.test.com"
        val name = ReflectionTestUtils.invokeMethod<String>(cookieHelper, GET_COOKIE_DOMAIN_METHOD, request)
        Assert.assertEquals(".test.com", name)
    }

    @Test
    fun testWwwSubDomainCom() {
        val request = MockHttpServletRequest()
        request.serverName = "www.abc.test.com"
        val name = ReflectionTestUtils.invokeMethod<String>(cookieHelper, GET_COOKIE_DOMAIN_METHOD, request)
        Assert.assertEquals(".test.com", name)
    }


    @Test
    fun testCoUkDomain() {
        val request = MockHttpServletRequest()
        request.serverName = "test.co.uk"
        val name = ReflectionTestUtils.invokeMethod<String>(cookieHelper, GET_COOKIE_DOMAIN_METHOD, request)
        Assert.assertNull(name)            //already top-level domain
    }

    @Test
    fun testCoUkSubDomain() {
        val request = MockHttpServletRequest()
        request.serverName = "abc.test.co.uk"
        val name = ReflectionTestUtils.invokeMethod<String>(cookieHelper, GET_COOKIE_DOMAIN_METHOD, request)
        Assert.assertEquals(".test.co.uk", name)
    }

    @Test
    fun testNestedDomain() {
        val request = MockHttpServletRequest()
        request.serverName = "abc.xyu.test.co.uk"
        val name = ReflectionTestUtils.invokeMethod<String>(cookieHelper, GET_COOKIE_DOMAIN_METHOD, request)
        Assert.assertEquals(".test.co.uk", name)
    }

    @Test
    fun testIpAddress() {
        val request = MockHttpServletRequest()
        request.serverName = "127.0.0.1"
        val name = ReflectionTestUtils.invokeMethod<String>(cookieHelper, GET_COOKIE_DOMAIN_METHOD, request)
        Assert.assertNull(name)
    }

    companion object {
        const val GET_COOKIE_DOMAIN_METHOD = "getCookieDomain"
    }
}
